package com.kool.kmetrics.service;

import com.kool.kmetrics.client.RedisClient;
import com.kool.kmetrics.common.util.DateUtil;
import com.kool.kmetrics.constant.PacketTypeEnum;
import com.kool.kmetrics.vo.MetricsVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Optional;

import static com.kool.kmetrics.constant.MetricsRedisKey.*;

/**
 * @author luyu
 * @date 2021-04-19 22:50
 */
@Service
@Slf4j
public class QueryService {
    @Resource
    private RedisClient redisClient;

    /**
     * 查询平台指标
     *
     * @return
     */
    public MetricsVo getGlobalCnt() {
        String minute = DateUtil.dateString(new Date(), "yyyyMMddHHmm");
        String day = minute.substring(0, 8);

        //会话数
        String sessionCntValue = redisClient.get(String.format(KEY_SESSION_CNT, minute));
        long sessionCnt = Long.parseLong(Optional.ofNullable(sessionCntValue).orElse("0"));

        long receiveTotal = 0L;
        long receiveSuccess = 0L;
        long receiveFail = 0L;
        long sumCost = 0L;
        long maxCost = 0L;
        long sendTotal = 0L;
        long sendSuccess = 0L;
        long sendFail = 0L;

        //汇总所有报文类型
        for (PacketTypeEnum packetTypeEnum : PacketTypeEnum.values()) {
            //入站总数
            String receiveTotalValue = redisClient.get(String.format(KEY_TODAY_RECEIVE_TOTAL, day, packetTypeEnum.getCode(), "global", "global"));
            receiveTotal = receiveTotal + Long.parseLong(Optional.ofNullable(receiveTotalValue).orElse("0"));

            //入站成功数
            String receiveSuccessValue = redisClient.get(String.format(KEY_TODAY_RECEIVE_SUCCESS, day, packetTypeEnum.getCode(), "global", "global"));
            receiveSuccess = receiveSuccess + Long.parseLong(Optional.ofNullable(receiveSuccessValue).orElse("0"));

            //入站失败数
            String receiveFailValue = redisClient.get(String.format(KEY_TODAY_RECEIVE_FAIL, day, packetTypeEnum.getCode(), "global", "global"));
            receiveFail = receiveFail + Long.parseLong(Optional.ofNullable(receiveFailValue).orElse("0"));
            //入站耗时总和
            String sumCostValue = redisClient.get(String.format(KEY_TODAY_RECEIVE_COST_SUM, day, packetTypeEnum.getCode(), "global", "global"));
            sumCost = sumCost + Long.parseLong(Optional.ofNullable(sumCostValue).orElse("0"));
            //入站最大耗时
            String maxCostValue = redisClient.get(String.format(KEY_TODAY_RECEIVE_COST_MAX, day, packetTypeEnum.getCode(), "global", "global"));
            long tmpMax = Long.parseLong(Optional.ofNullable(maxCostValue).orElse("0"));
            if (tmpMax > maxCost) {
                maxCost = tmpMax;
            }
            //出站总数
            String sendTotalValue = redisClient.get(String.format(KEY_TODAY_SEND_TOTAL, day, packetTypeEnum.getCode(), "global", "global"));
            sendTotal = sendTotal + Long.parseLong(Optional.ofNullable(sendTotalValue).orElse("0"));
            //出站成功数
            String sendSuccessValue = redisClient.get(String.format(KEY_TODAY_SEND_SUCCESS, day, packetTypeEnum.getCode(), "global", "global"));
            sendSuccess = sendSuccess + Long.parseLong(Optional.ofNullable(sendSuccessValue).orElse("0"));
            //出站失败数
            String sendFailValue = redisClient.get(String.format(KEY_TODAY_SEND_FAIL, day, packetTypeEnum.getCode(), "global", "global"));
            sendFail = sendFail + Long.parseLong(Optional.ofNullable(sendFailValue).orElse("0"));
        }

        //入站平均耗时
        long avgCost = 0L;
        if (receiveSuccess > 0) {
            avgCost = sumCost / receiveSuccess;
        }

        MetricsVo metrics = new MetricsVo();
        metrics.setSessionCnt(sessionCnt)
                .setReceiveTotal(receiveTotal)
                .setReceiveSuccess(receiveSuccess)
                .setReceiveFail(receiveFail)
                .setAvgCost(avgCost)
                .setMaxCost(maxCost)
                .setSendTotal(sendTotal)
                .setSendSuccess(sendSuccess)
                .setSendFail(sendFail);

        return metrics;
    }
}
